package file;

import commands.BaseCmd;
import commands.Cmd;
import common.Strings;
import error.Errors;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

public class File
{
	String fileAlias;
	String fileName;
	public FileType fileType;
	String fileAfter;
	ArrayList<FileString> strings;

	public BaseCmd baseCommand;

	public File(String fileName)
	{
		fileAlias = (new java.io.File(fileName)).getName().toUpperCase();
		this.fileName = fileName;
		fileType = FileType.INCLUDE;
		fileAfter = "";
		strings = new ArrayList<FileString>();

		BufferedReader reader;
		try
		{
			reader = new BufferedReader(new FileReader(fileName));
		}
		catch (Exception exc)
		{
			Errors.addError(fileName, fileAlias, -1, "OpenFile:" + exc.toString());
			fileType = FileType.BAD;
			return;
		}

		int i = 2;
		try
		{
			String line;
			if ((line = reader.readLine()) != null && isFirstLineCorrect(line))
				while ((line = reader.readLine()) != null)
					strings.add(new FileString(fileName, fileAlias, i++, line));
		}
		catch (Exception exc)
		{
			Errors.addError(fileName, fileAlias, i, "FileRead:" + exc.toString());
			fileType = FileType.BAD;
		}
	}

	boolean isFirstLineCorrect(String str)
	{
		ArrayList<String> elems = Strings.getSimpleKeyEquSting(str);
		if (elems == null)
		{
			Errors.addError(fileName, fileAlias, 1, "Ошибка парсинга первой строки");
			fileType = FileType.BAD;
			return false;
		}
		if (elems.size() % 2 != 0)
		{
			Errors.addError(fileName, fileAlias, 1,
					"У одного из ключей нет параметра (КЛЮЧ=ЗНАЧЕНИЕ) в строке: '" + str + "'");
			fileType = FileType.BAD;
			return false;
		}
		for (int i = 0; i < elems.size(); i += 2)
		{
			if (elems.get(i).equalsIgnoreCase("name"))
				fileAlias = elems.get(i + 1).toUpperCase();
			else if (elems.get(i).equalsIgnoreCase("parse"))
			{
				fileType = null;
				for (FileType t : FileType.values())
					if (elems.get(i + 1).equalsIgnoreCase(t.toString()))
						fileType = t;
				if (fileType == null)
				{
					Errors.addError(fileName, fileAlias, 1,
							"Недопустимый параметр ключа PARSE: '" + elems.get(i + 1) + "'");
					fileType = FileType.BAD;
					return false;
				}
			}
			else if (elems.get(i).equalsIgnoreCase("after"))
				fileAfter = elems.get(i + 1).toUpperCase();
			else
			{
				fileType = FileType.BAD;
				Errors.addError(fileName, fileAlias, 1, "Недопустимый ключ в заголовке файла: '" + elems.get(i) + "'");
			}
		}
		if (!IsAnyPlace() && fileType != FileType.INCLUDE && fileType != FileType.STATIC_INCLUDE)
			Errors.addWarning(fileName, fileAlias, 1,
					"Параметр AFTER не имеет смысла для файлов с PARSE=" + fileType + "; Используется только с INCLUDE и STATIC_INCLUDE");
		return true;
	}

	public boolean IsAnyPlace()
	{
		return (fileAfter.length() == 0);
	}

	public void generateCommands()
	{
		baseCommand = new BaseCmd(fileName, fileAlias);
		for (FileString str : strings)
			baseCommand.addCommandToBody(Cmd.getCommand(str));
		if(baseCommand.emptyAndCommentStrings.size()>0)
		for(Cmd tCmd : baseCommand.emptyAndCommentStrings)
			baseCommand.body.add(tCmd);
		baseCommand.emptyAndCommentStrings.clear();
	}
}
